﻿#建议保存编码为：bom头 + utf8

param
(
	[parameter(Mandatory = $true)]
	[ValidateNotNullOrEmpty()]
	[Alias("filename")][String]$k4t文件全名,

	[byte]$_本脚本递归次数
)

if ( ($IsWindows -eq $True) -or ($PSVersionTable.psversion.major -lt 6) ) #win
{
	Write-Error '错误：不支持win系统，退出码1'
	exit 1
}

$env:LANG = 'zh_CN.UTF-8'
& "${PSScriptRoot}/k4t_client_config.ps1"


[string]${Private:当前应用名} = $k4t文件全名.
tolower().
replace('/etc/kasini3000/k4t_client/shoubao/','').
replace('/k4t.xml','').
split('/')
#${Private:当前应用名}

Set-Location '/etc/kasini3000/k4t_client/shoubao/'
try
{
	Set-Location ${Private:当前应用名} -ErrorAction 'stop'
}
catch
{
	& "${PSScriptRoot}/k4t_锁写log.ps1"  "错误：应用名错误！ ${Private:当前应用名} ，退出码4"
	exit 4
}

if (Test-Path -LiteralPath './191' -PathType Container)
{
	if (Test-Path -LiteralPath './191/miao_di_jia_beng.txt')
	{
		Write-Verbose '信息：寿报已经停用'
		Set-Location ../..
		exit 6
	}
}
else
{
	& "${PSScriptRoot}/_jl建立呼吸机目录.ps1" ${Private:当前应用名}
	& "${PSScriptRoot}/_s删除所有呼吸机并重建初始呼吸机.ps1" ${Private:当前应用名}
}

if (Test-Path -LiteralPath './ping_an_wu_shi.huxiji')
{
	$Private:平安无事文件 = Get-ChildItem -File -LiteralPath './ping_an_wu_shi.huxiji'
	$Private:寿报文件 = Get-ChildItem -File -LiteralPath './k4t.xml'
	if ($Private:平安无事文件.LastWriteTime -gt $Private:寿报文件.LastWriteTime)
	{
		exit 5
	}
	else
	{
		Remove-Item -LiteralPath $Private:平安无事文件
	}
}

if (Test-Path -LiteralPath './lan_xiang_jiao_pi.txt')
{
	$Private:temp003 = Get-ChildItem -File -LiteralPath './lan_xiang_jiao_pi.txt'
	if (((Get-Date) - $Private:temp003.LastWriteTime) -lt [timespan]::FromSeconds(160))
	{
		exit 2
	}
}
else
{
	New-Item -ItemType File -Force -Path './lan_xiang_jiao_pi.txt'
}

$Private:寿报表 = Import-Clixml -LiteralPath './k4t.xml'

$Private:呼吸机 = Get-ChildItem -Path './hu_xi_ji.txt' -File -Recurse
#$Private:呼吸机

if ($Private:呼吸机.count -eq 1)
{
	$Private:呼吸机目录 = $Private:呼吸机.fullname.
	replace('/hu_xi_ji.txt','').
	replace('/etc/kasini3000/k4t_client/shoubao/','').
	replace(${Private:当前应用名},'').
	replace('/','')
}
else
{
	& "${PSScriptRoot}/_s删除所有呼吸机并重建初始呼吸机.ps1" ${Private:当前应用名}
	& "${PSScriptRoot}/k4t_锁写log.ps1"  "错误：呼吸机太多，或太少！ ${Private:当前应用名} ，退出码3"
	Set-Location ../..
	exit 3
}

#$Private:呼吸机目录

switch ($Private:呼吸机目录)
{
	'111'
	{
		#docker login，或mount镜像的nfs
		if (Test-Path -LiteralPath './pull_image_before/docker_login.ps1')
		{
			& './pull_image_before/docker_login.ps1'
		}

		#导入.tar镜像
		$Private:tar镜像文件 = Get-ChildItem -Path './image/*' -File
		if ( ($Private:tar镜像文件 -eq $null) -or ($Private:tar镜像文件 -eq '') )
		{
			# 检查是否已经存在镜像
			[string]$private:是否有此镜像 = docker image ls | grep ${Private:寿报表}.镜像名 | grep ${Private:寿报表}.镜像版本
			if ( ($private:是否有此镜像 -eq $null) -or ($private:是否有此镜像 -eq '') )
			{
				#状态=镜像未下载。动作=下载镜像。
				& "${PSScriptRoot}/_docker_pull下载镜像.ps1" -image名 ${Private:寿报表}.镜像名 -image版本  ${Private:寿报表}.镜像版本 -应用名 ${Private:当前应用名}
				Move-Item -LiteralPath $Private:呼吸机 -Destination './112' -Force
			}
			else
			{
				Move-Item -LiteralPath $Private:呼吸机 -Destination './113' -Force
			}
		}
		else
		{
			docker image load -i $Private:tar镜像文件.fullname
			Start-Sleep -Seconds 2
			Remove-Item -Force -LiteralPath $Private:tar镜像文件.fullname
			Move-Item -LiteralPath $Private:呼吸机 -Destination './113' -Force
		}
		break
	}

	'112'
	{
		[string]$private:是否有此镜像 = docker image ls | grep ${Private:寿报表}.镜像名 | grep ${Private:寿报表}.镜像版本
		if ( ($private:是否有此镜像 -eq $null) -or ($private:是否有此镜像 -eq '') )
		{
			#状态=镜像下载中。动作=检查镜像下载进程，有进程若超时，则增加镜像错误次数。
			$private:docker_pull超时 = (Get-ChildItem -File -LiteralPath './docker_pull_pid.txt').LastWriteTime.AddSeconds($global:docker_pull超时秒)
			if ((Get-Date) -gt $private:docker_pull超时)
			{
				if ($Private:寿报表.镜像下载已经出错次数 -gt $global:尝试docker_pull最大次数 )
				{
					& "${PSScriptRoot}/shoubao_写log.ps1" "错误: 镜像下载失败！$Private:当前应用名"
					Move-Item -LiteralPath $Private:呼吸机 -Destination './203' -Force
					New-Item -ItemType File -Force -Path './!bug!.txt'
					New-Item -ItemType File -Force -Path './191/miao_di_jia_beng.txt'
				}
				else
				{
					$Private:寿报表.镜像下载已经出错次数 = $Private:寿报表.镜像下载已经出错次数 + 1
					& "${PSScriptRoot}/_xie写入寿报文件.ps1" -寿报表 ${Private:寿报表}
					$Private:镜像下载进程id = Get-Content -LiteralPath './docker_pull_pid.txt'
					Stop-Process $Private:镜像下载进程id
					Move-Item -LiteralPath $Private:呼吸机 -Destination './111' -Force
				}
				Remove-Item -Force -LiteralPath './docker_pull_pid.txt'
			}
		}
		else
		{
			#触发容器滚动更新。
			New-Item -ItemType File -Force -Path './an_quan_tou_kui.txt'
		}
		break
	}

	'113'
	{
		Remove-Item -Force -LiteralPath './docker_pull_pid.txt'
		$Private:寿报表.已经重启过的次数 = 0
		& "${PSScriptRoot}/_xie写入寿报文件.ps1" -寿报表 ${Private:寿报表}

		if (Test-Path -LiteralPath './pull_image_after/docker_logout.ps1')
		{
			& './pull_image_after/docker_logout.ps1'
		}

		Move-Item -LiteralPath $Private:呼吸机 -Destination './121' -Force
		$_本脚本递归次数 = 1
		break
	}

	'121'
	{
		#呼吸机，敢问路在何方
		#检查node节点排斥本请用情况。
		$Private:有node级排斥 = & "${PSScriptRoot}/____checkp检查linux的node上的一种应用排斥.ps1" -应用的uuid ${Private:寿报表}.uuid
		if ($Private:有node级排斥 -eq $true)
		{
			New-Item -ItemType File -Force -Path './!bug!.txt'
			& "${PSScriptRoot}/shoubao_写log.ps1" "错误: node上有node级排斥，应用将终止。"
			Move-Item -LiteralPath $Private:呼吸机 -Destination './201' -Force
			New-Item -ItemType File -Force -Path './191/miao_di_jia_beng.txt'
			break
		}

		#检查本应用，排斥其他应用情况。
		$Private:应用级别排斥 = $false
		foreach (${Private:被测试的寿报uuid} in $Private:寿报表.有其他寿报的uuid之一_本寿报就不运行)
		{
			if (Test-Path -LiteralPath "/etc/kasini3000/k4t_client/app_uuid/${Private:被测试的寿报uuid}")
			{
				$Private:应用级别排斥 = $true
				break
			}
		}
		if ($Private:应用级别排斥 -eq $true)
		{
			New-Item -ItemType File -Force -Path './!bug!.txt'
			& "${PSScriptRoot}/shoubao_写log.ps1" "错误: 被本应用排斥的，其他应用已经运行，本应用无法运行！${Private:被测试的寿报uuid} "
			Move-Item -LiteralPath $Private:呼吸机 -Destination './202' -Force
			New-Item -ItemType File -Force -Path './191/miao_di_jia_beng.txt'
			break
		}

		#读取寿报副本数
		$private:当前寿报副本数 = ${Private:寿报表}.寿报副本数_本节点_现有

		if (${Private:寿报表}.寿报副本数_本节点_设定 -gt 0)
		{
			$private:当前寿报最大副本数 = ${Private:寿报表}.寿报副本数_本节点_设定
			$private:当前寿报最小副本数 = ${Private:寿报表}.寿报副本数_本节点_设定
		}
		else
		{
			$private:当前寿报最大副本数 = ${Private:寿报表}.寿报最大副本数_本节点_设定
			$private:当前寿报最小副本数 = ${Private:寿报表}.寿报最小副本数_本节点_设定
		}

		if ($Private:寿报表.寿报已经启用 -eq $true)
		{
			if (Test-Path -LiteralPath "/etc/kasini3000/k4t_client/app_uuid/$(${Private:寿报表}.uuid)")
			{
			}
			else
			{
				New-Item -ItemType File -Force -Path "/etc/kasini3000/k4t_client/app_uuid/$(${Private:寿报表}.uuid)"
			}
		}
		else
		{
			if ($private:当前寿报副本数 -le 0)
			{
				Remove-Item -Force -LiteralPath "/etc/kasini3000/k4t_client/app_uuid/$(${Private:寿报表}.uuid)"
				Remove-Item -Force -LiteralPath $Private:呼吸机
				Remove-Item -Force -LiteralPath './!bug!.txt'
				New-Item -ItemType File -Force -Path './191/miao_di_jia_beng.txt'
				break
			}
			else
			{
				if (Test-Path -LiteralPath './!bug!.txt')
				{
				}
				else
				{
					New-Item -ItemType File -Force -Path './!bug!.txt'
				}
				break
			}
		}

		if ($private:当前寿报副本数 -lt $private:当前寿报最小副本数)
		{
			if (${Private:寿报表}.每node内_尝试启动应用最大次数 -eq 0)
			{
				${Private:寿报最大重启次数} = $global:每node内_尝试启动应用最大次数
			}
			else
			{
				${Private:寿报最大重启次数} = ${Private:寿报表}.每node内_尝试启动应用最大次数
			}

			if (${Private:寿报表}.已经重启过的次数 -gt ${Private:寿报最大重启次数})
			{
				& "${PSScriptRoot}/shoubao_写log.ps1" "错误: 寿报启动次数，超出最大次数！"
				Move-Item -LiteralPath $Private:呼吸机 -Destination './204' -Force
				New-Item -ItemType File -Force -Path './ping_an_wu_shi.huxiji'
			}
			else
			{
				if (${Private:寿报表}.是无双寿报 -eq $true)
				{
					Move-Item -LiteralPath $Private:呼吸机 -Destination './132' -Force
				}
				else
				{
					Move-Item -LiteralPath $Private:呼吸机 -Destination './131' -Force
					$_本脚本递归次数 = 1
				}
			}
		}
		elseif ($private:当前寿报副本数 -gt $private:当前寿报最大副本数)
		{
			if (Test-Path -LiteralPath './fei_yu_guan_tou.txt')
			{
			}
			else
			{
				New-Item -ItemType File -Force -Path './fei_yu_guan_tou.txt'
			}
		}
		else
		{
			if (${Private:寿报表}.应用负载均衡算法 -eq '使用node节点上的sc自动伸缩脚本')
			{
				#使用node节点上的sc自动伸缩脚本
				if (Test-Path -LiteralPath './scalable_copies/sc.ps1')
				{
					[int16]$private:变更寿报副本数 = & './scalable_copies/sc.ps1'
				}

				if ($private:变更寿报副本数 -eq 1)
				{
					if (${Private:寿报表}.每node内_尝试启动应用最大次数 -eq 0)
					{
						${Private:寿报最大重启次数} = $global:每node内_尝试启动应用最大次数
					}
					else
					{
						${Private:寿报最大重启次数} = ${Private:寿报表}.每node内_尝试启动应用最大次数
					}

					if (${Private:寿报表}.已经重启过的次数 -gt ${Private:寿报最大重启次数})
					{
						& "${PSScriptRoot}/shoubao_写log.ps1" "错误: 寿报启动次数，超出最大次数！"
						Move-Item -LiteralPath $Private:呼吸机 -Destination './204' -Force
						New-Item -ItemType File -Force -Path './ping_an_wu_shi.huxiji'
					}
					else
					{
						if (${Private:寿报表}.是无双寿报 -eq $true)
						{
							Move-Item -LiteralPath $Private:呼吸机 -Destination './132' -Force
						}
						else
						{
							Move-Item -LiteralPath $Private:呼吸机 -Destination './131' -Force
							$_本脚本递归次数 = 1
						}
					}
				}

				if ($private:变更寿报副本数 -eq -1)
				{
					if (Test-Path -LiteralPath './fei_yu_guan_tou.txt')
					{
					}
					else
					{
						New-Item -ItemType File -Force -Path './fei_yu_guan_tou.txt'
					}
				}
			}
			else
			{
				New-Item -ItemType File -Force -Path './ping_an_wu_shi.huxiji'
			}
		}
		break
	}

	'131'
	{
		#普通寿报，获取ip开始。
		$Private:所有ip地址_ipv4 = Get-ChildItem -Path "${PSScriptRoot}/ip_pool/*.ipv4" -File
		if ( ($Private:所有ip地址_ipv4 -eq $null) -or ($Private:所有ip地址_ipv4 -eq '') )
		{
			& "${PSScriptRoot}/shoubao_写log.ps1" "错误: ${Private:当前应用名} 获取ipv4 ip地址失败！"
			$Private:ipv4_ip地址_获取失败的log文件 = "/etc/kasini3000/k4t_client/shoubao/${Private:当前应用名}/get_ipv4_fall.txt"
			if (Test-Path -LiteralPath $Private:ipv4_ip地址_获取失败的log文件)
			{
				[byte]$Private:ipv4获取失败次数 = Get-Content -LiteralPath $Private:ipv4_ip地址_获取失败的log文件 -Encoding utf8BOM
				$Private:ipv4获取失败次数++
				Set-Content -LiteralPath $Private:ipv4_ip地址_获取失败的log文件 -Value $Private:ipv4获取失败次数 -Encoding utf8BOM
				if ($Private:ipv4获取失败次数 -gt $global:普通寿报_尝试获取ipv4地址最大次数)
				{
					Move-Item -LiteralPath $Private:呼吸机 -Destination './205' -Force
					New-Item -ItemType File -Force -Path './ping_an_wu_shi.huxiji'
				}
			}
			else
			{
				Set-Content -LiteralPath $Private:ipv4_ip地址_获取失败的log文件 -Value 1 -Encoding utf8BOM
			}
		}
		else
		{
			$Private:随机ip地址_ipv4 = Get-Random -InputObject $Private:所有ip地址_ipv4
			Remove-Item -Force -LiteralPath $Private:随机ip地址_ipv4.fullname
			New-Item -ItemType File -Force -Path "/etc/kasini3000/k4t_client/shoubao/${Private:当前应用名}/$(${Private:随机ip地址_ipv4}.name)"
			Move-Item -LiteralPath $Private:呼吸机 -Destination './133' -Force
			$_本脚本递归次数 = 1
		}
		break
	}

	'132'
	{
		#启动无双寿报
		Move-Item -LiteralPath $Private:呼吸机 -Destination './121' -Force
		break
	}

	'133'
	{
		#启动普通寿报
		$Private:有驱逐点 = & "${PSScriptRoot}/____checkq检查linux的node上的驱逐点.ps1"
		if ($Private:有驱逐点 -eq $true)
		{
			& "${PSScriptRoot}/shoubao_写log.ps1" "错误: node上有驱逐点，无法启动寿报。"
			New-Item -ItemType File -Force -Path './191/miao_di_jia_beng.txt'
			break
		}

		${Private:有污点} = & "${PSScriptRoot}/____checkw检查linux的node上的污点.ps1"
		if (${Private:有污点} -eq $true)
		{
			& "${PSScriptRoot}/shoubao_写log.ps1" "错误: node上有污点，无法启动寿报。"
			New-Item -ItemType File -Force -Path './ping_an_wu_shi.huxiji'
			break
		}

		${Private:剩余内存} = & "${PSScriptRoot}/hqm获取空闲内存MB_当前实时值_win_linux通用1.ps1"
		if (${Private:剩余内存} -lt $global:node最小保留内存_MB)
		{
			& "${PSScriptRoot}/shoubao_写log.ps1" "错误: node上内存不足，无法启动寿报。${Private:剩余内存}"
			New-Item -ItemType File -Force -Path './ping_an_wu_shi.huxiji'
			break
		}

		${Private:剩余cpu} = & "${PSScriptRoot}/hq获取cpu空闲_当前实时值_win_linux通用3.ps1"
		if ((${Private:剩余cpu} * 100) -lt $global:node最小保留cpu_百分比)
		{
			& "${PSScriptRoot}/shoubao_写log.ps1" "错误: node上cpu不足，无法启动寿报。${Private:剩余cpu}"
			New-Item -ItemType File -Force -Path './ping_an_wu_shi.huxiji'
			break
		}

		$Private:口罩0 = Get-ChildItem -File -Path './*.ipv4'
		if ( ($Private:口罩0 -eq $null) -or ($Private:口罩0 -eq '') )
		{
			& "${PSScriptRoot}/shoubao_写log.ps1" "错误:  ${Private:当前应用名} 应用目录内，找不到【ipv4文件】，无法启动寿报。"
			break
		}

		if ($Private:口罩0 -is [array])
		{
			$Private:口罩00 = $Private:口罩0[0]
		}
		else
		{
			$Private:口罩00 = $Private:口罩0
		}
		[string]$Private:口罩00ip = $Private:口罩00.basename

		[string]$private:docker_cmd = "docker container run {0} {1} {2} {3} -p {4}:{5}:{6}{7} {8} {9} {10}:{11}" -f ${Private:寿报表}.寿报cpu参数,${Private:寿报表}.寿报内存参数,${Private:寿报表}.环境变量,${Private:寿报表}.其他参数,$Private:口罩00ip,${Private:寿报表}.宿主机端口,${Private:寿报表}.寿报内端口,${Private:寿报表}.协议,${Private:寿报表}.容器挂载卷1,${Private:寿报表}.容器挂载卷2,${Private:寿报表}.镜像名,${Private:寿报表}.镜像版本
		& "${PSScriptRoot}/shoubao_写log.ps1" "信息：容器启动命令行是：`n$private:docker_cmd"

		$private:容器id = Invoke-Expression -Command $private:docker_cmd
		$private:容器id2 = $private:容器id.Substring(0,12)
		Start-Sleep -Seconds 5

		$private:校验容器 = docker container ls | grep $private:容器id2
		if ( ($private:校验容器 -eq $null) -or ($private:校验容器 -eq '') -or ($private:容器id2 -eq '' ) )
		{
			& "${PSScriptRoot}/shoubao_写log.ps1" "错误: 容器启动失败！容器启动命令行是：`n$private:docker_cmd"
			${Private:寿报表}.已经重启过的次数 = ${Private:寿报表}.已经重启过的次数 + 1
			& "${PSScriptRoot}/_xie写入寿报文件.ps1" -寿报表 ${Private:寿报表}

			if (${Private:寿报表}.每node内_尝试启动应用最大次数 -eq 0)
			{
				${Private:寿报最大重启次数} = $global:每node内_尝试启动应用最大次数
			}
			else
			{
				${Private:寿报最大重启次数} = ${Private:寿报表}.每node内_尝试启动应用最大次数
			}

			if (${Private:寿报表}.已经重启过的次数 -gt ${Private:寿报最大重启次数})
			{
				New-Item -ItemType File -Force -Path "/etc/kasini3000/k4t_client/ip_pool/${Private:口罩00ip}.ipv4"
				Remove-Item -LiteralPath $Private:口罩00.fullname -Force
				& "${PSScriptRoot}/shoubao_写log.ps1" "错误: 寿报启动次数，超出最大次数！"
				Move-Item -LiteralPath $Private:呼吸机 -Destination './204' -Force
				New-Item -ItemType File -Force -Path './ping_an_wu_shi.huxiji'
			}
		}
		else
		{
			${Private:寿报表}.寿报副本数_本节点_现有 = ${Private:寿报表}.寿报副本数_本节点_现有 + 1
			& "${PSScriptRoot}/_xie写入寿报文件.ps1" -寿报表 ${Private:寿报表}
			$Private:temp002 = ${Private:口罩00}.basename + '_' + $private:容器id2 + '.kouzhao1'
			Rename-Item -Force -LiteralPath $Private:口罩00.fullname -NewName $Private:temp002
			Move-Item -LiteralPath $Private:呼吸机 -Destination './121' -Force
		}
		break
	}

	default
	{
		& "${PSScriptRoot}/shoubao_写log.ps1" "错误: 错误的呼吸机！${Private:呼吸机目录} "
	}
}

Remove-Item -Force -LiteralPath './lan_xiang_jiao_pi.txt'

if ($_本脚本递归次数 -gt 0)
{
	# & "${PSScriptRoot}/shoubao_写log.ps1" "从呼吸机 $Private:呼吸机目录 进入递归"
	$_本脚本递归次数--
	& "$PSCommandPath" -k4t文件全名 $k4t文件全名 -_本脚本递归次数 $_本脚本递归次数
}

Set-Location ../..
exit 0
